
#include<stdio.h>
 
//注意由于matrix大小(可以更改)给定，能最大生成10阶幻方
bool check(int matrix[10][10],int n)//判断是否为幻方 
{
	int sum=0;
	int temp=0;
	int i=0,j=0,k=0;
	for( i=0;i<n;i++)
		sum=sum+matrix[0][i];//得到一行或列的总和
	for(j=1;j<n;j++)//检查行
	{
		temp=0;
		for(k=0;k<n;k++)
			temp=temp+matrix[j][k];
		if(temp!=sum)
			return false;
		
	}
	for( j=0;j<n;j++)//检查列
	{
		temp=0;
		for(k=0;k<n;k++)
			temp=temp+matrix[k][j];
		if(temp!=sum)
			return false;
	}
	temp=0;
	for(i=0;i<n;i++)
		temp=temp+matrix[i][i];//检查主对角线
	if(temp!=sum)
		return false;
 
	temp=0;
	for(i=0;i<n;i++)
		temp=temp+matrix[i][n-1-i];//检测副对角线
	if(temp!=sum)
		return false;
printf("该方阵为幻方！\n");
return true;
 
}
 
void Odd(int n,int matrix[10][10])//奇数阶幻方
{
	int i=0,j=n/2;
	int number=1;
	for(int k=0;k<n*n;k++)
	{
		matrix[i][j]=number;
			
		i--;
		j++;
		number++;
 
		if(i<0&&j<n)//出上界
		{
			i=n-1;
			
		}
		else if(i>=0&&j>=n)//出右界
		{
			j=0;
		}
		else if(i<0&&j>=n)//右、上出界
		{
		
			if(matrix[n-1][0]!=0)//底格放
			{
				i=i+2;
				j=j-1;
			}
			else
			{
			i=n-1;
			j=0;
			}
 
		}
		if(matrix[i][j]!=0)//底格放
		{
			i=i+2;
			j=j-1;
		}
	}
}
 
 
void DoubleEven(int n,int matrix[10][10])//双偶数阶幻方
{
 
	int number=1;
	int temp=0;
	int i=0,j=0,k=0;
	for(i=0;i<n;i++)
		for(j=0;j<n;j++)
			matrix[i][j]=number++;//初始化
 
	for(i=0;i<n;i=i+4)
		for(j=0;j<n;j=j+4)
			for(k=0;k<4;k++)
			{
				matrix[i+k][j+k]=n*n+1-matrix[i+k][j+k];//每个对角线的数换成互补的数
				matrix[i+k][j+3-k]=n*n+1-matrix[i+k][j+3-k];
			}
 
}
 
void SingleEven(int n,int matrix[10][10])//单偶数阶幻方
{
	int degree=n/2;
	int flag=n/4;
	int i=0,j=0,k=0;
	int temp=0;
 
	int matrix1[10][10]={0};//将大矩阵化为A B C D四个小矩阵
	int matrix2[10][10]={0};
	int matrix3[10][10]={0};
	int matrix4[10][10]={0};
 
	Odd(degree,matrix1);//对每一个矩阵进行奇数幻方算法
	for(i=0;i<degree;i++)
		for(j=0;j<degree;j++)
		{
			matrix2[i][j]=matrix1[i][j]+degree*degree;
			matrix3[i][j]=matrix1[i][j]+degree*degree*2;
			matrix4[i][j]=matrix1[i][j]+degree*degree*3;
		}
 
	for(i=0;i<degree;i++)//对A C矩阵按照规则进行数据交换
		for(j=0;j<flag;j++)
			if(i!=(degree/2))
			{
				temp=matrix1[i][j];
				matrix1[i][j]=matrix4[i][j];
				matrix4[i][j]=temp;
			}
			else
			{
				temp=matrix1[i][j+degree/2];
				matrix1[i][j+degree/2]=matrix4[i][j+degree/2];
				matrix4[i][j+degree/2]=temp;
			}
	for(i=0;i<degree;i++)//对B D矩阵按照规则进行数据交换
		for(j=0;j<flag-1;j++)
		{
			temp=matrix2[i][j+degree/2];
			matrix2[i][j+degree/2]=matrix3[i][j+degree/2];
			matrix3[i][j+degree/2]=temp;
		}
 
 
		//将新的四个矩阵赋给幻方矩阵matrix
		for(i=0;i<degree;i++)
		{
			for(j=0;j<degree;j++)
				matrix[i][j]=matrix1[i][j];
	
			for(k=0;k<degree;k++)
				matrix[i][j+k]=matrix3[i][k];
 
		}
		for(i=0;i<degree;i++)
		{
			for(j=0;j<degree;j++)
				matrix[i+degree][j]=matrix4[i][j];
 
			for(k=0;k<degree;k++)
				matrix[i+degree][j+k]=matrix2[i][k];
 
		}
 
}
 
 
int main()
{
	int matrix[10][10]={0};
	int n;	printf("%d",6%2);
	printf("请输入幻方的阶数：");
	scanf("%d",&n);
 
 
	if(n%2!=0)
		Odd(n,matrix);
	else if(n%4!=0)
		SingleEven(n,matrix);
	else
		DoubleEven(n,matrix);
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
				printf("%d ",matrix[i][j]);
			printf("\n");
		}
 
		check(matrix,n);//检测是否为幻方
}
//
//————————————————
//版权声明：本文为CSDN博主「nineheaded_bird」的原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接及本声明。
//原文链接：https://blog.csdn.net/tengweitw/article/details/17687377